"""
API网关统一配置模块
==================

基于RedFire框架的统一配置管理
整合所有配置需求，消除配置地狱
"""

import os
import yaml
from pathlib import Path
from typing import Dict, List, Any, Optional
from pydantic import BaseModel, Field, validator
from enum import Enum


class LoadBalancingStrategy(str, Enum):
    """负载均衡策略"""
    ROUND_ROBIN = "round_robin"
    WEIGHTED_ROUND_ROBIN = "weighted_round_robin"
    LEAST_CONNECTIONS = "least_connections"
    RANDOM = "random"
    IP_HASH = "ip_hash"


class ServiceInstance(BaseModel):
    """服务实例配置"""
    host: str = Field(..., description="服务主机地址")
    port: int = Field(..., ge=1, le=65535, description="服务端口")
    weight: int = Field(default=100, ge=1, le=1000, description="负载均衡权重")
    health_check_path: str = Field(default="/health", description="健康检查路径")
    timeout: float = Field(default=30.0, ge=0.1, le=300.0, description="连接超时时间")
    metadata: Dict[str, Any] = Field(default_factory=dict, description="实例元数据")


class RouteConfig(BaseModel):
    """路由配置"""
    path: str = Field(..., description="路由路径模式")
    service_name: str = Field(..., description="目标服务名称")
    target_path: str = Field(default="", description="目标路径")
    methods: List[str] = Field(default=["GET"], description="支持的HTTP方法")
    rate_limit: int = Field(default=100, ge=0, description="速率限制（请求/分钟）")
    circuit_breaker_enabled: bool = Field(default=True, description="是否启用熔断器")
    timeout: float = Field(default=30.0, ge=0.1, le=300.0, description="请求超时时间")
    retry_count: int = Field(default=3, ge=0, le=10, description="重试次数")
    auth_required: bool = Field(default=False, description="是否需要认证")
    priority: int = Field(default=100, ge=1, le=1000, description="路由优先级（越小越高）")
    middleware: List[str] = Field(default_factory=list, description="中间件列表")
    metadata: Dict[str, Any] = Field(default_factory=dict, description="路由元数据")
    
    @validator('methods')
    def validate_methods(cls, v):
        valid_methods = {"GET", "POST", "PUT", "DELETE", "PATCH", "OPTIONS", "HEAD"}
        for method in v:
            if method.upper() not in valid_methods:
                raise ValueError(f"Invalid HTTP method: {method}")
        return [m.upper() for m in v]


class APIGatewayConfig(BaseModel):
    """API网关配置模型"""
    
    # 基础服务信息
    service_name: str = Field(default="api-gateway", description="服务名称")
    service_version: str = Field(default="1.0.0", description="服务版本")
    environment: str = Field(default="development", description="运行环境")
    
    # 服务器配置
    host: str = Field(default="0.0.0.0", description="服务器主机")
    port: int = Field(default=8000, ge=1, le=65535, description="服务器端口")
    debug: bool = Field(default=True, description="调试模式")
    reload: bool = Field(default=True, description="自动重载")
    
    # 服务实例配置
    services: Dict[str, List[ServiceInstance]] = Field(default_factory=dict, description="服务实例配置")
    
    # 路由配置
    routes: List[RouteConfig] = Field(default_factory=list, description="路由配置列表")
    
    # WebSocket路由配置
    websocket_routes: List[Dict[str, Any]] = Field(default_factory=list, description="WebSocket路由配置列表")
    
    # WebSocket配置
    websocket: Dict[str, Any] = Field(default_factory=lambda: {
        "enabled": True,
        "max_connections": 1000,
        "timeout": 300,
        "heartbeat_interval": 30,
        "routes": [
            {
                "path": "/ws/market-data",
                "service_name": "market_data_service",
                "target_path": "/api/v1/market/ws/market-data",
                "auth_required": False
            }
        ]
    }, description="WebSocket配置")
    
    # Redis配置
    redis: Dict[str, Any] = Field(default_factory=lambda: {
        "host": "localhost",
        "port": 6379,
        "password": None,
        "db": 0,
        "timeout": 5.0,
        "max_connections": 10
    }, description="Redis配置")
    
    # 负载均衡配置
    load_balancing: Dict[str, Any] = Field(default_factory=lambda: {
        "strategy": LoadBalancingStrategy.WEIGHTED_ROUND_ROBIN,
        "health_check_enabled": True,
        "health_check_timeout": 5.0,
        "health_check_interval": 30,
        "failure_threshold": 3,
        "success_threshold": 2
    }, description="负载均衡配置")
    
    # 监控配置
    monitoring: Dict[str, Any] = Field(default_factory=lambda: {
        "metrics_enabled": True,
        "request_logging": True,
        "error_logging": True,
        "performance_tracking": True,
        "slow_request_threshold": 1.0
    }, description="监控配置")
    
    # 安全配置
    security: Dict[str, Any] = Field(default_factory=lambda: {
        "cors_enabled": True,
        "cors_origins": ["*"],
        "cors_methods": ["GET", "POST", "PUT", "DELETE", "OPTIONS"],
        "cors_headers": ["*"],
        "cors_credentials": True,
        "jwt_secret_key": "default-secret-key",
        "jwt_algorithm": "HS256",
        "jwt_expire_minutes": 30,
        "security_headers_enabled": True
    }, description="安全配置")
    
    # 日志配置 - 容器化友好
    logging: Dict[str, Any] = Field(default_factory=lambda: {
        "level": "INFO",
        "format": "json",
        "access_log": True,
        "error_log": True,
        "log_file": None,  # 输出到stdout，容器化友好
        "max_file_size": 100,
        "backup_count": 5,
        "console_output": True  # 强制控制台输出
    }, description="日志配置")
    
    # 性能配置
    performance: Dict[str, Any] = Field(default_factory=lambda: {
        "connection_timeout": 30.0,
        "read_timeout": 30.0,
        "max_connections": 100,
        "max_keepalive_connections": 20,
        "keepalive_expiry": 5.0,
        "pool_size": 10,
        "pool_timeout": 5.0
    }, description="性能配置")
    
    # 数据库配置
    database_url: str = Field(default="sqlite:///./redfire_gateway.db", description="数据库连接URL")
    database_pool_size: int = Field(default=10, description="数据库连接池大小")
    
    # JWT配置
    jwt_secret_key: str = Field(default="development-jwt-secret-key-change-in-production-32chars-minimum", description="JWT密钥")
    jwt_algorithm: str = Field(default="HS256", description="JWT算法")
    jwt_expire_minutes: int = Field(default=30, description="JWT过期时间（分钟）")
    
    # 全局开关
    rate_limiting_enabled: bool = Field(default=True, description="是否启用速率限制")
    circuit_breaker_enabled: bool = Field(default=True, description="是否启用熔断器")
    
    class Config:
        """Pydantic配置"""
        env_prefix = "GATEWAY_"
        case_sensitive = False
        validate_assignment = True
        extra = "forbid"
    
    @property
    def is_development(self) -> bool:
        """是否为开发环境"""
        return self.environment.lower() == "development"
    
    @property
    def is_production(self) -> bool:
        """是否为生产环境"""
        return self.environment.lower() == "production"
    
    @property
    def is_testing(self) -> bool:
        """是否为测试环境"""
        return self.environment.lower() == "testing"
    
    def get_routes_by_priority(self) -> List[RouteConfig]:
        """按优先级排序的路由列表"""
        return sorted(self.routes, key=lambda r: r.priority)
    
    def get_service_instances(self, service_name: str) -> List[ServiceInstance]:
        """获取指定服务的实例列表"""
        return self.services.get(service_name, [])


def get_default_services() -> Dict[str, List[ServiceInstance]]:
    """获取默认服务配置"""
    return {
        "user_service": [
            ServiceInstance(
                host="localhost",
                port=8002,
                weight=100,
                health_check_path="/health"
            )
        ],
        "market_data_service": [
            ServiceInstance(
                host="localhost",
                port=8001,
                weight=100,
                health_check_path="/health"
            )
        ]
    }


def get_default_routes() -> List[RouteConfig]:
    """获取默认路由配置"""
    return [
        # 用户服务认证路由
        RouteConfig(
            path="/api/v1/auth/*",
            service_name="user_service",
            target_path="/api/v1/auth",
            methods=["GET", "POST", "PUT", "DELETE"],
            rate_limit=100,
            circuit_breaker_enabled=True,
            timeout=30.0,
            retry_count=3,
            auth_required=False,
            priority=10,
            metadata={
                "description": "用户认证相关接口",
                "tags": ["auth", "user"]
            }
        ),
        # 用户服务管理路由
        RouteConfig(
            path="/api/v1/users/*",
            service_name="user_service",
            target_path="/api/v1/users",
            methods=["GET", "POST", "PUT", "DELETE"],
            rate_limit=100,
            circuit_breaker_enabled=True,
            timeout=30.0,
            retry_count=3,
            auth_required=True,
            priority=20,
            metadata={
                "description": "用户管理接口",
                "tags": ["user", "management"]
            }
        ),
        # 市场数据服务路由
        RouteConfig(
            path="/api/v1/market-data/*",
            service_name="market_data_service",
            target_path="/api/v1/market-data",
            methods=["GET", "POST"],
            rate_limit=500,
            circuit_breaker_enabled=True,
            timeout=10.0,
            retry_count=2,
            auth_required=False,
            priority=30,
            metadata={
                "description": "市场数据接口",
                "tags": ["market", "data", "public"]
            }
        )
    ]


def load_config_from_yaml(config_path: str = None) -> Dict[str, Any]:
    """
    从YAML文件加载配置
    
    Args:
        config_path: 配置文件路径
        
    Returns:
        Dict[str, Any]: 配置数据
    """
    if config_path is None:
        # 默认配置文件路径
        current_dir = Path(__file__).parent.parent
        config_path = current_dir / "config.yml"
    
    try:
        with open(config_path, 'r', encoding='utf-8') as f:
            config_data = yaml.safe_load(f)
        return config_data or {}
    except FileNotFoundError:
        print(f"Warning: Config file not found: {config_path}")
        return {}
    except yaml.YAMLError as e:
        print(f"Error parsing YAML config: {e}")
        return {}


def get_api_gateway_config(environment: str = None, config_path: str = None) -> APIGatewayConfig:
    """
    获取API Gateway配置
    
    Args:
        environment: 环境名称 (development/testing/production)
        config_path: 配置文件路径
        
    Returns:
        APIGatewayConfig: 配置实例
    """
    if environment is None:
        environment = os.getenv("GATEWAY_ENVIRONMENT", "development")
    
    # 从YAML文件加载配置
    config_data = load_config_from_yaml(config_path)
    
    # 如果YAML文件为空，使用默认配置
    if not config_data:
        config_data = {
            "environment": environment,
            "services": get_default_services(),
            "routes": get_default_routes()
        }
    
    # 环境变量覆盖
    config_data["environment"] = environment
    
    # 环境特定配置覆盖
    if environment == "production":
        config_data.update({
            "debug": False,
            "reload": False
        })
        
        # 更新安全配置
        security_config = config_data.get("security", {})
        security_config.update({
            "jwt_secret_key": os.getenv("GATEWAY_JWT_SECRET_KEY", security_config.get("jwt_secret_key", "production-secret-key")),
            "cors_origins": ["https://redfire.com", "https://app.redfire.com"]
        })
        config_data["security"] = security_config
        
        # 更新日志配置 - 生产环境容器化友好
        logging_config = config_data.get("logging", {})
        logging_config.update({
            "level": "INFO",
            "format": "json",
            "log_file": None,  # 生产环境输出到stdout
            "console_output": True
        })
        config_data["logging"] = logging_config
        
    elif environment == "testing":
        config_data.update({
            "debug": True,
            "reload": False,
            "port": 8100
        })
        
        # 更新安全配置
        security_config = config_data.get("security", {})
        security_config.update({
            "jwt_secret_key": "testing-secret-key",
            "cors_origins": ["http://localhost:3000"]
        })
        config_data["security"] = security_config
        
        # 更新日志配置
        logging_config = config_data.get("logging", {})
        logging_config.update({
            "level": "DEBUG"
        })
        config_data["logging"] = logging_config
    
    return APIGatewayConfig(**config_data)


def validate_api_gateway_config(config: APIGatewayConfig) -> tuple[bool, List[str]]:
    """
    验证API Gateway配置
    
    Args:
        config: 配置实例
        
    Returns:
        tuple: (是否有效, 错误信息列表)
    """
    errors = []
    
    # 验证JWT密钥
    jwt_secret = config.security.get("jwt_secret_key", "")
    if jwt_secret in ["default-secret-key", "production-secret-key"]:
        if config.is_production:
            errors.append("Production environment must use a secure JWT secret key")
        else:
            errors.append("JWT secret key should be changed from default")
    
    # 验证服务实例
    if not config.services:
        errors.append("At least one service instance must be configured")
    
    # 验证路由配置
    if not config.routes:
        errors.append("At least one route must be configured")
    
    # 验证路由路径唯一性
    paths = [route.path for route in config.routes]
    if len(paths) != len(set(paths)):
        errors.append("Route paths must be unique")
    
    # 验证服务引用
    service_names = set(config.services.keys())
    route_services = {route.service_name for route in config.routes}
    missing_services = route_services - service_names
    if missing_services:
        errors.append(f"Routes reference undefined services: {missing_services}")
    
    return len(errors) == 0, errors
